#pragma once
#include "EventLoop.h"
#include "Socket.h"
#include "Channel.h"
#include "Acceptor.h"
#include "Connection.h"
#include "ThreadPool.h"
#include <map>
#include <memory>
#include <mutex>
//TCP网络服务类
class TcpServer
{
private:
    std::unique_ptr<EventLoop> main_loop_;    //主事件循环
    std::vector<std::unique_ptr<EventLoop>> sub_loops_; //存放从事件循环的容器
    Acceptor acceptor_;    //一个TcpServer只有一Acceptor对象
    int threadNum_;                 //线程池大小，即从事件循环个数
    ThreadPool threadPool_;     //线程池
    std::mutex mmutex_;         //维护conns_的互斥锁 
    std::map<int, spConnection> conns_;   //一个TcpServer有多个Connection对象，存放在map容器中

    //回调EchoServer中的函数
    std::function<void(spConnection)> new_Connection_Cb_;        
    std::function<void(spConnection)> close_Connection_Cb_;
    std::function<void(spConnection)> error_Connection_Cb_;
    std::function<void(spConnection, std::string &message)> on_Message_Cb_;
    std::function<void(spConnection)> send_Complete_Cb_;
    std::function<void(EventLoop*)> timeout_Cb_;
public:
    TcpServer(const std::string& ip, const uint16_t port, int threadNum = 3);
    ~TcpServer();

    void start();   //运行事件循环
    void stop();    //停止IO线程和事件循环

    void new_Connection(std::unique_ptr <Socket> clientSock);          //处理新客户端连接请求
    void close_Connection(spConnection conn);          //关闭客户端的连接，在Connection类中回调此函数
    void error_Connection(spConnection conn);          //客户端的连接错误，在Connection类中回调此函数
    void on_Message(spConnection conn, std::string& message);    //处理客户端的请求报文，在Connection中回调该函数
    void send_Complete(spConnection conn);              //数据发送完成的函数，在Connection类中回调此函数
    void epoll_TimeOut(EventLoop* loop);               //epoll_wait()超时，在EventLoop类中回调此函数

    void set_new_Connection_Cb_(std::function<void(spConnection)> func);
    void set_close_Connection_Cb_(std::function<void(spConnection)> func);
    void set_error_Connection_Cb_(std::function<void(spConnection)> func);
    void set_on_Message_Cb_(std::function<void(spConnection, std::string &message)> func);
    void set_send_Complete_Cb_(std::function<void(spConnection)> func);
    void set_timeout_Cb_(std::function<void(EventLoop*)> func);

    void removeConn(int fd);    //删除Conns_中的Connection对象，在EventLoop::handletimer()中将回调此函数
};